﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Conversion_Script
{
    class FrequencyDistributions
    {

        static int[,] GetExtremeMapValues(string variable)
        {
            int[,] extremes = new int[Landscape.LandUseNames.Length,2];

            for (int l = 0; l < Landscape.LandUseNames.Length; l++)
            {
                extremes[l,0] = int.MaxValue;
                extremes[l, 1] = int.MinValue;
            }
            int t = 0;
            while (t < Settings.GetSimulationLength())
            {
                ASCII LandUse = new ASCII(Output.FileName( Settings.Get(Settings.Get(KeyWords.Scenarioname)), KeyWords.LandUse, KeyWords.LandUse, t));
                ASCII Mass = new ASCII(Output.FileName(Settings.Get(KeyWords.Scenarioname), variable, variable, t));

                for (int r = 0; r < LandUse.Nrows; r++)
                {
                    for (int c = 0; c < LandUse.Ncols; c++)
                    {
                        int l = LandUse[r, c];
                        int v = Mass[r, c];
                        if (v < extremes[l, 0]) extremes[l, 0] = v;
                        if (v > extremes[l, 1]) extremes[l, 1] = v;
                    }
                }
                t += int.Parse(Settings.Get(KeyWords.TimeStep));
            }
            return extremes;
        }
        static int[,] GetCategoryBoundaries(int NrOfCohorts, string variable)
        {
            int[,] CategoryBoundaries = new int[Landscape.LandUseNames.Length, NrOfCohorts+1];

            int[,] ExtremeValues = GetExtremeMapValues(variable);

            for (int l = 0; l < Landscape.LandUseNames.Length; l++)
            {
                float CohortWidth = 1.0F/(float)NrOfCohorts * (ExtremeValues[l, 1] - ExtremeValues[l, 0]);
                float WidthCounter = 0;
                for (int c = 1; c <= NrOfCohorts; c++)
                {
                    WidthCounter += CohortWidth;
                    CategoryBoundaries[l, c] = (int)(ExtremeValues[l, 0] + WidthCounter);
                }
                CategoryBoundaries[l, NrOfCohorts]++;
            }

            return CategoryBoundaries;
        }
        public static Matrix[] GetDistributions(int NrOfCohorts, string variable)
        {
            Matrix[] Distributions = new Matrix[Landscape.LandUseNames.Length];

            int[,] CategoryBoundaries = GetCategoryBoundaries(NrOfCohorts, variable);

            for (int l = 0; l < Landscape.LandUseNames.Length; l++)
            {
                string[] Headers = new string[NrOfCohorts+1];
                Headers[0] = "Time";
                for (int c = 1; c <= NrOfCohorts; c++) Headers[c] = variable + "[" + CategoryBoundaries[l, c-1].ToString() + "," + CategoryBoundaries[l, c].ToString() +"]";

                Distributions[l] = new Matrix(Settings.GetSimulationLength() + 1,Headers);

                int t = 0;
                while(t < Settings.GetSimulationLength())
                {
                    Distributions[l].SetValue(t, 0, (t).ToString());
                    for (int c = 1; c < NrOfCohorts+1; c++)
                    {
                        Distributions[l].SetValue(t, c, (0).ToString());
                    }
                    t += int.Parse(Settings.Get(KeyWords.TimeStep));
                }
                


            }
            int t2 = 0;
            while (t2 < Settings.GetSimulationLength())
            {
                ASCII LandUse = new ASCII(Output.FileName(Settings.Get(KeyWords.Scenarioname), KeyWords.LandUse, KeyWords.LandUse, t2));// dunno
                ASCII Mass = new ASCII(Output.FileName(Settings.Get(KeyWords.Scenarioname), variable, variable, t2));

                for (int r = 0; r < Landscape.LandUseMap.Nrows; r++)
                {
                    for (int c = 0; c < Landscape.LandUseMap.Ncols; c++)
                    {
                        int value = Mass[r, c];
                        int landuse = LandUse[r, c];
                        bool AccountedFor = false;
                        for (int cohort = 1; cohort <= NrOfCohorts; cohort++)
                        {
                            if ((value >= CategoryBoundaries[landuse, cohort - 1] && value < CategoryBoundaries[landuse, cohort]) 
                                || (value >= CategoryBoundaries[landuse, cohort - 1] && CategoryBoundaries[landuse, cohort - 1] == CategoryBoundaries[landuse, cohort])
                                || (cohort ==  NrOfCohorts &&  value == CategoryBoundaries[landuse, cohort]))
                            {
                                try
                                {
                                    Distributions[landuse].AddValue(t2, cohort, 1);
                                }
                                catch
                                {
                                    double t = 0.0;
                                }
                                AccountedFor=true;
                                break;
                            }
                        }
                        if(!AccountedFor)
                        {
                            throw new System.Exception("Cannot find cohort for simulation value "+ variable+" "+ value);
                        }
                        
                    }
                }
                t2 += int.Parse(Settings.Get(KeyWords.TimeStep));
            }



            return Distributions;
        
        }
    }
}
